﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AudiPyme.BLL
{
    //Clase que se usa en el cálculo de riesgos y recoge una amenaza, los controles asociados a ella según la base de conocimiento y la
    //cobertura que dichos controles generan
    public class ProbabilidadVulnerabilidad : IComparable
    {
        private int idAmenaza;
        private List<ControlesCheckList> controlesAmenazaVuln;
        private int coberturaControlesAmenazaVuln;

        public ProbabilidadVulnerabilidad()
        {
            idAmenaza = 0;
            controlesAmenazaVuln = new List<ControlesCheckList>();
            coberturaControlesAmenazaVuln = 0;
        }

        public ProbabilidadVulnerabilidad(int idAmenaza, List<ControlesCheckList> controlesAmenazaVuln, int coberturaControlesAmenazaVuln)
        {
            this.idAmenaza = idAmenaza;
            this.controlesAmenazaVuln = controlesAmenazaVuln;
            this.coberturaControlesAmenazaVuln = coberturaControlesAmenazaVuln;
        }
        public int IdAmenaza
        {
            get { return idAmenaza; }
            set { idAmenaza = value; }
        }
        public List<ControlesCheckList> ControlesAmenazaVuln
        {
            get { return controlesAmenazaVuln; }
            set { controlesAmenazaVuln = value; }
        }
        public int CoberturaControlesAmenazaVuln
        {
            get { return coberturaControlesAmenazaVuln; }
            set { coberturaControlesAmenazaVuln = value; }
        }

        public int CompareTo(object obj)
        {
            ProbabilidadVulnerabilidad otroProbabVuln = obj as ProbabilidadVulnerabilidad;
            if (otroProbabVuln == null)
            {
                return 0;
            }
            switch (CoberturaControlesAmenazaVuln.CompareTo(otroProbabVuln.CoberturaControlesAmenazaVuln))
            {
                case 1:
                    return -1;
                case -1:
                    return 1;
                default:
                    return CoberturaControlesAmenazaVuln.CompareTo(otroProbabVuln.CoberturaControlesAmenazaVuln);
            }
        }

        //Método que sirve para calcular la cobertura de los controles asociados a una amenaza, según las respuesta a estos por parte de la empresa
        public int CalculaCoberturaContrAmenaza(List<ControlesCheckList> ControlesAmenaza)
        {
            //Inicializo el Nivel de Riesgo con un valor centinela
            int nivelRiesgo = -1;
            double resultadoControles = 0.0;
            //Creo las variables para poder contar el número de valores distintos de los controles
            int nControlesSI = 0, nControlesNO = 0, nControlesPARC = 0, nControlesNA = 0;
            //Recorro la lista de controles y actualizo las variables con los valores de cada uno
            for (int i = 0; i < ControlesAmenaza.Count(); i++)
            {
                switch (ControlesAmenaza[i].ValorControl)
                {
                    case "SI":
                        nControlesSI++;
                        break;
                    case "NO":
                        nControlesNO++;
                        break;
                    case "PARC":
                        nControlesPARC++;
                        break;
                    case "N/A":
                        nControlesNA++;
                        break;
                }
            }
            /*Calculo el Nivel de Riesgo que produce esa Amenaza según esta fórmula
             * 
             *                            NºControles SI + (NºControles PARCIALMENTE * 0.5)
             * ResultadoControles = ------------------------------------------------------------------
             *                        (NºControles Totales de la Amenaza) - (NºControles NO APLICA)
             *                   
             * Dicho resultado lo normalizamos siguiendo esta metodología:
             *          0 <= ResultadoControles < 0.25    =>   Nivel Riesgo = 2 (Alto)
             *       0.25 <= ResultadoControles < 0.75    =>   Nivel Riesgo = 1 (Medio)
             *       0.75 <= ResultadoControles < 1       =>   Nivel Riesgo = 0 (Bajo)
             */
            resultadoControles = (nControlesSI + (nControlesPARC * 0.5)) / (ControlesAmenaza.Count() - nControlesNA);
            if (resultadoControles < 0.25)
            {
                //RiesgoAlto
                nivelRiesgo = 2;
            }
            else if (resultadoControles < 0.75)
            {
                //RiesgoMedio
                nivelRiesgo = 1;
            }
            else
            {
                //RiesgoBajo
                nivelRiesgo = 0;
            }

            return nivelRiesgo;
        }
    }
}
